package org.lex.app.sessions;

import java.awt.Component;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.SwingWorker;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

import org.lex.utils.Codec;
import org.lex.utils.text.Splitter;


public class JTableSession extends AbstractSession {
	private static final String COLUMN_WIDTH = "columnWidths";
	private static final String SORT_KEYS = "sortKeys";

	@Override
	public Session getComponentProperties(Component c) {
		this.clear();
		JTable table = (JTable) c;
		// columnWidths
		TableColumnModel cm = table.getColumnModel();
		int[] widths = new int[cm.getColumnCount()];
		for (int i = 0; i < widths.length; i++)
			widths[i] = cm.getColumn(i).getWidth();
		this.putProperty(COLUMN_WIDTH, Codec.encodeIntegerArray(widths));
		// sortOrder
		RowSorter<? extends TableModel> sorter = table.getRowSorter();
		if (null != sorter) {
			List<? extends RowSorter.SortKey> keys = sorter.getSortKeys();
			if (false == keys.isEmpty()) {
				StringBuilder buf = new StringBuilder();
				Iterator<? extends RowSorter.SortKey> iter = keys.iterator();
				while (true) {
					buf.append(this.encodeSortKey(iter.next()));
					if (iter.hasNext())
						buf.append(',');
					else
						break;
				}
				this.putProperty(SORT_KEYS, buf.toString());
			}
		}
		return this;
	}

	@Override
	public void restoreComponent(final Component c) {
		/*
		 * XXX which one is better, SwingWorker or SwingUtilities??
		 * ������,SwintUtilities �� restore-session��ʱ����٣���������ʱgui��
		 * ��һ���Ƚ����Ե�ͣ�١��Ա�֮�£�SwingWorker��ʱ���࣬��������gui�Ƚ� ƽ��������
		 * û������ͣ��
		 */
		new SwingWorker<Void, Void>() {
			@Override
			protected Void doInBackground() throws Exception {
				restore(c);
				return null;
			}
		}.execute();
		// SwingUtilities.invokeLater( new Runnable(){
		// public void run()
		// {
		// restore( c );
		// }
		// } );
	}

	private void restore(Component c) {
		JTable table = (JTable) c;
		// columnWidths
		String str = this.getProperty(COLUMN_WIDTH);
		if (null != str && false == str.isEmpty()) {
			int[] widths = Codec.decodeIntegerArray(str);
			TableColumnModel cm = table.getColumnModel();
			int columnCount = cm.getColumnCount();
			for (int i = 0; i < columnCount; i++)
				cm.getColumn(i).setPreferredWidth(widths[i]);
		}
		// sortOrder
		String raw = this.getProperty(SORT_KEYS);
		if (null != raw && false == raw.isEmpty()) {
			String[] tokens = Splitter.CommaSplitter.split(raw);
			if (0 != tokens.length) {
				ArrayList<RowSorter.SortKey> list = new ArrayList<RowSorter.SortKey>(tokens.length);
				for (String token : tokens) {
					RowSorter.SortKey key = this.decodeSortKey(token);
					if (null != key)
						list.add(key);
				}
				table.getRowSorter().setSortKeys(list);
			}
		}
	}

	private String encodeSortKey(RowSorter.SortKey key) {
		return key.getColumn() + " " + key.getSortOrder().name();
	}

	private RowSorter.SortKey decodeSortKey(String input) {
		String[] token = Splitter.BlankSpaceSplitter.split(input);
		if (2 != token.length)
			return null;
		return new RowSorter.SortKey(Integer.parseInt(token[0]), SortOrder.valueOf(token[1]));
	}
}
